package com.xxxx.tx.send;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.nio.charset.StandardCharsets;

/**
 * 事物-消息生产者
 */
public class Send {

    // 定义队列名称
    private final static String QUEUE_NAME = "tx";

    public static void main(String[] argv) throws Exception {
        // 创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        // rabbitmq服务开启的虚拟机地址
        factory.setHost("192.168.1.105");
        // 登录rabbitmq的用户名、密码
        factory.setUsername("yeb");
        factory.setPassword("yeb");
        // 虚拟地址
        factory.setVirtualHost("/yeb");
        // 端口号
        factory.setPort(5672);

        // **********************
        Connection connection = null;
        Channel channel = null;
        // **********************

        try {
            // 连接工厂创建连接
            connection = factory.newConnection();
            // 创建信道
            channel = connection.createChannel();

            // *********************
            // 开启事物
            channel.txSelect();
            // *********************
            /**
             * 声明队列
             * 第一个参数queue：队列名称
             * 第二个参数durable：是否持久化
             * 第三个参数Exclusive：排他队列，如果一个队列被声明为排他队列，该队列仅对首次
             * 声明它的连接可见，并在连接断开时自动删除。
             *     这里需要注意三点：
             *         1. 排他队列是基于连接可见的，同一连接的不同通道是可以同时访问同一个
             * 连接创建的排他队列的。
             *         2. "首次"，如果一个连接已经声明了一个排他队列，其他连接是不允许建
             * 立同名的排他队列的，这个与普通队列不同。
             *         3. 即使该队列是持久化的，一旦连接关闭或者客户端退出，该排他队列都会
             * 被自动删除的。
             *         这种队列适用于只限于一个客户端发送读取消息的应用场景。
             * 第四个参数Auto-delete：自动删除，如果该队列没有任何订阅的消费者的话，该队列
             * 会被自动删除。
             *                         这种队列适用于临时队列。
             */
            channel.queueDeclare(QUEUE_NAME, false, false, false, null);
            // 创建消息
            String message = "Hello World!";
//            int i = 1 / 0;  // 测试回滚时使用的数据
            // 将产生的消息放入队列
            channel.basicPublish("", QUEUE_NAME, null, message.getBytes(StandardCharsets.UTF_8));
            // ********************
            // 提交事物
            channel.txCommit();
            // ********************
            System.out.println(" [x] Sent '" + message + "'");

        } catch (Exception e) {
            e.printStackTrace();
            // 回滚事物
            channel.txRollback();
        }
    }
}